
/**
* @fileoverview
* peach的核心组件，用于构造peach对象与相关的基础信息。
*
* @author xudaosong
*/
/**
* 它是基于jquery，具备面向对象、AMD、Build等为一体的新一代JavaScript框架库，代号为peach（桃子）
* @namespace peach
* @name peach
*
* @author xudaosong
*/
define('base/kernel',[],function(){
	// 初始化peach配置
	var config = {}, userConfig = this["peachConfig"], p;
	for(p in userConfig){
		config[p] = userConfig[p];
	}
	// 定义peach变量
	var peach = /** @lends peach */{
		/**
		 * peach的全局对象，一般是window对象
		 */
		global: this,
		/**
		 * peach的全局配置。
		 * noGlobals: 如果为true，则peach纳入全局的对象(window对象)，否则为false
		 */
		config: config
	};
	// 定义全局对象，如果全局中已经存在peach则纳入_peach
	if(!config.noGlobals){
		if (typeof this["peach"] === "undefined") {
			this["peach"] = peach;
		} else if (typeof this["peach"] !== "object" && typeof this["peach"] !== "function") {
			peach["_peach"] = this["peach"];
		}
	}
	/**
	* 定义产品的版本信息.如： 1.0.0beta1
	* @type Object
	*/
	peach.version = {
		major: 1, minor: 0, patch: 0, flag: "beta1",
		toString: function () {
			with (peach.version) {
				return major + "." + minor + "." + patch + flag; // String
			}
		}
	};
	return peach;
});
/**
 * @fileoverview
 * 特性检测模块
 * @author xudaosong
 */
define('has',["./base/kernel"], function(g){
    var NON_HOST_TYPES = { "boolean": 1, "number": 1, "string": 1, "undefined": 1 },
        VENDOR_PREFIXES = ["Webkit", "Moz", "O", "ms", "Khtml"],
        d = isHostType(g, "document") && g.document,
        el = d && isHostType(d, "createElement") && d.createElement("DiV"),
        testCache = {};
	/**
	 * 特性检测方法，支持构建工具进行代码过滤
	 * @param {String} name 需要检测的特性名称，该特性名称是通过has.add注册的。
	 * @returns Boolean
     * @namespace peach.has
	 * @name peach.has
     * @example 检测是否支持touch特性
     * if(has("touch")){
     *      // todo: is touch
     * }
	 */
    function has(name){
        if(typeof testCache[name] == "function"){
            testCache[name] = testCache[name](g, d, el);
        }
        return testCache[name];
    }
	/**
	 * 注册新的特性检测
	 * @memberOf peach.has
	 * @param {String} name 特性名称
	 * @param {Function} test 测试特性的方法。该方法返回Boolean值，代表是否支持该特性。该方法有三个参数：global(全局peach对象),document（文档对象）,element（为该测试生成的元素对象）
	 * @param {Boolean} [now]  是否立即执行测试
     * @example 立即执行简单的测试
     * has.add("javascript", function(){ return true; }, true);
     * @example 注册touch特性检测
     * has.add("touch", function(g, d, el){
     *      // g  == 全局peach对象
     *      // d  == 文档对象
     *      // el == 生成的元素对象
     *      return false;
     * }
	 */
    function add(name, test, now){
        testCache[name] = now ? test(g, d, el) : test;
    }

    // cssprop adapted from http://gist.github.com/598008 (thanks, ^pi)
    function cssprop(name, el){
        var supported = false,
            capitalized = name.charAt(0).toUpperCase() + name.slice(1),
            length = VENDOR_PREFIXES.length,
            style = el.style;

        if(typeof style[name] == "string"){
            supported = true;
        }else{
            while(length--){
                if(typeof style[VENDOR_PREFIXES[length] + capitalized] == "string"){
                    supported = true;
                    break;
                }
            }
        }
        return supported;
    }

    function clearElement(el){
        if(el){
            while(el.lastChild){
                el.removeChild(el.lastChild);
            }
        }
        return el;
    }

    // Host objects can return type values that are different from their actual
    // data type. The objects we are concerned with usually return non-primitive
    // types of object, function, or unknown.
    function isHostType(object, property){
        var type = typeof object[property];
        return type == "object" ? !!object[property] : !NON_HOST_TYPES[type];
    }

        has.add = add;
    has.clearElement = clearElement;
    has.cssprop = cssprop;
    has.isHostType = isHostType;
    has._tests = testCache;

    has.add("dom", function(g, d, el){
        return d && el && isHostType(g, "location") && isHostType(d, "documentElement") &&
            isHostType(d, "getElementById") && isHostType(d, "getElementsByName") &&
            isHostType(d, "getElementsByTagName") && isHostType(d, "createComment") &&
            isHostType(d, "createElement") && isHostType(d, "createTextNode") &&
            isHostType(el, "appendChild") && isHostType(el, "insertBefore") &&
            isHostType(el, "removeChild") && isHostType(el, "getAttribute") &&
            isHostType(el, "setAttribute") && isHostType(el, "removeAttribute") &&
            isHostType(el, "style") && typeof el.style.cssText == "string";
    });

    // Stop repeat background-image requests and reduce memory consumption in IE6 SP1
    // http://misterpixel.blogspot.com/2006/09/forensic-analysis-of-ie6.html
    // http://blogs.msdn.com/b/cwilso/archive/2006/11/07/ie-re-downloading-background-images.aspx?PageIndex=1
    // http://support.microsoft.com/kb/823727
    try{
        document.execCommand("BackgroundImageCache", false, true);
    }catch(e){}
	return has;
});

/**
 * @fileoverview
 * 特性嗅探器模块
 * @author xudaosong
 */
define('sniff',["./has"], function (has) {
    /**
	 * 特性嗅探器，该模块用于嗅探当前浏览器的类型
	 * @returns has Function
     * @namespace peach.sniff
	 * @name peach.sniff
     * @example 检测是否是ie浏览器
     * define("./sniff",function(has){
     *  if(has("ie")){
     *      // todo: is ie
     *  }
     * });
	 */
    var isBrowser =
		    typeof window != "undefined" &&
		    typeof location != "undefined" &&
		    typeof document != "undefined" &&
		    window.location == location && window.document == document;
    has.add("host-browser", isBrowser);
    if (has("host-browser")) {
        var n = navigator,
			dua = n.userAgent,
			dav = n.appVersion,
			tv = parseFloat(dav);

        has.add("air", dua.indexOf("AdobeAIR") >= 0),
		has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined);
        has.add("webkit", parseFloat(dua.split("WebKit/")[1]) || undefined);
        has.add("chrome", parseFloat(dua.split("Chrome/")[1]) || undefined);
        has.add("safari", dav.indexOf("Safari") >= 0 && !has("chrome") ? parseFloat(dav.split("Version/")[1]) : undefined);
        has.add("mac", dav.indexOf("Macintosh") >= 0);
        has.add("quirks", document.compatMode == "BackCompat");
        has.add("ios", /iPhone|iPod|iPad/.test(dua));
        has.add("android", parseFloat(dua.split("Android ")[1]) || undefined);

        if (!has("webkit")) {
            // Opera
            if (dua.indexOf("Opera") >= 0) {
                // see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
                // 9.8 has both styles; <9.8, 9.9 only old style
                has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv);
            }

            // Mozilla and firefox
            if (dua.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")) {
                has.add("mozilla", tv);
            }
            if (has("mozilla")) {
                //We really need to get away from this. Consider a sane isGecko approach for the future.
                has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined);
            }

            // IE
            if (document.all && !has("opera")) {
                var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;

                //In cases where the page has an HTTP header or META tag with
                //X-UA-Compatible, then it is in emulation mode.
                //Make sure isIE reflects the desired version.
                //document.documentMode of 5 means quirks mode.
                //Only switch the value if documentMode's major version
                //is different from isIE's major version.
                var mode = document.documentMode;
                if (mode && mode != 5 && Math.floor(isIE) != mode) {
                    isIE = mode;
                }

                has.add("ie", isIE);
            }

            // Wii
            has.add("wii", typeof opera != "undefined" && opera.wiiremote);
        }
    }

    return has;
});

/**
 * @fileoverview
 * Javascript语言进行扩展
 *
 * @author xudaosong
 */
define('base/lang',["./kernel", "../jquery", "../has", "../sniff"], function (peach, $, has) {
    // 初始化对象基类的公共成员名称
    var extraNames, extraLen,
    empty = {},
    _extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
    for (var i in { toString: 1 }) { extraNames = []; break; }
    extraLen = extraNames.length;
    /**
     * 获取parts数组里最后一个对象，如果对象链接不存在则返回undefined
     *
     * @param {String[]} parts 对象链的数组
     * @param {Boolean} create 如果对象链不存在是否创建
     * @param {Object} context （可选）对象链的根对象，默认是dojo.global对象为根对象
     *
     * @return Object|undefined
     *
     * @example
     * peach._getProp(["peach","bar"],true);// 返回peach.bar里的bar对象
     */
    var getProp = function (parts, create, context) {
        var p, i = 0, global = peach.global, scopeMap = peach.scopeMap;
        if (!context) {
            if (!parts.length) {
                return global;
            } else {
                p = parts[i++];
                try {
                    context = scopeMap[p] && scopeMap[p][1];
                } catch (e) {
                }
                context = context
						|| (p in global ? global[p] : (create ? global[p] = {}
								: undefined));
            }
        }
        while (context && (p = parts[i++])) {
            context = (p in context ? context[p] : (create ? context[p] = {}
					: undefined));
        }
        return context; // mixed
    };
    var efficient = function (obj, offset, startWith) {
        return (startWith || []).concat(Array.prototype.slice.call(obj, offset || 0));
    };
    var _pattern = /\{([^\}]+)\}/g;
    var lang =/** @lends  peach */ {
        _extraNames: _extraNames,
        /**
         * 将source的所有属性与方法添加到target.
         * 如果两个对象中有相同的字段，那么source中的同名字段将替换target中的字段。
         *
         * @param {Object} target 被合并的对象
         * @param {Object} source 需要进行合并的对象
         *
         * @return obj
         *
         */
        _mixin: function (target, source) {
            var name, s, i;
            for (name in source) {
                s = source[name];
                if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
                    target[name] = s;
                }
            }
            if (extraLen && source) {
                for (i = 0; i < extraLen; ++i) {
                    name = extraNames[i];
                    s = source[name];
                    if (!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))) {
                        target[name] = s;
                    }
                }
            }
            return target;
        },
        _toArray: has("ie") ?
			(function () {
			    function slow(obj, offset, startWith) {
			        var arr = startWith || [];
			        for (var x = offset || 0; x < obj.length; x++) {
			            arr.push(obj[x]);
			        }
			        return arr;
			    }
			    return function (obj) {
			        return ((obj.item) ? slow : efficient).apply(this, arguments);
			    };
			})() : efficient,
        _hitchArgs: function (scope, method) {
            var pre = lang._toArray(arguments, 2);
            var named = lang.isString(method);
            return function () {
                // arrayify arguments
                var args = lang._toArray(arguments);
                // locate our method
                var f = named ? (scope || peach.global)[method] : method;
                // invoke with collected args
                return f && f.apply(scope || this, pre.concat(args)); // mixed
            }; // Function
        },
        /**
		 * 设置指定的scope作为method的作用域。
		 * @param { Object } scope method的作用域对象
		 * @param { Function | String } method 钩住作用域的方法或作用域里的方法名使用此作用域。
		 * @returns { Function } 返回包含scope作用域的method方法。
		 * @example 在foo作用域下运行foo.bar()
		 * lang.hitch(foo, "bar")();
		 * @example 返回foo作用域下myfunction方法
		 * lang.hitch(foo, myFunction);
		 * @example 设置默认参数
		 * var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
		 * var fn = lang.hitch(foo, "bar", 1, 2);
		 * fn(3); // logs "1, 2, 3"
		 * @example 为匿名方法指定作用域
		 * var foo = { bar: 2 };
		 * lang.hitch(foo, function(){ this.bar = 10; })();
		 */
        hitch: function (scope, method) {
            if (arguments.length > 2) {
                return lang._hitchArgs.apply(peach, arguments); // Function
            }
            if (!method) {
                method = scope;
                scope = null;
            }
            if (lang.isString(method)) {
                scope = scope || peach.global;
                if (!scope[method]) { throw (['lang.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
                return function () { return scope[method].apply(scope, arguments || []); }; // Function
            }
            return !scope ? method : function () { return method.apply(scope, arguments || []); };
        },
        /**
         * 用于将对象混合在一起。
         * 所谓mixin（混入）是将两个对象从右到左组合起来，覆盖最左边的对象，并且返回混入后的对象给用户。
         *
         * @param {Object} obj 被混入的对象
         * @param {Object} props 混入到obj的对象，可以是多个对象
         *
         * @return obj
         *
         * @example
         * var a = { b:"c", d:"e" };
         * peach.mixin(a,{ d:"f", g:"h" });
         * console.log(a); // b:c, d:f, g:h
         */
        mixin: function (obj, props) {
            if (!obj) { obj = {}; }
            for (var i = 1, l = arguments.length; i < l; i++) {
                lang._mixin(obj, arguments[i]);
            }
            return obj; // Object
        },
        /**
		 * 设置用点分隔字符串的属性，如：A.B.C。
		 *
		 * @param {String}
		 *            name 属性的路径，如A.B.C
		 * @param {anything}
		 *            value 值或对象赋值给name
		 * @param {Object?}
		 *            context 对象的作用域，默认为peach.global
		 * @return {Object | undefined} 返回设置后的对象
		 * @example 设置foo.bar.baz的值，不管命名空间的对象是否存在
		 * lang.setObject("foo.bar.baz", value);
		 * @example
		 *  // 没有lang.setObject我们经常看到如下代码：
		 *  if(!obj["parent"]){ obj.parent = {}; }
		 *  if(!obj.parent["child"]){ obj.parent.child = {}; }
		 *  // 现在我们能安全的设置属性
		 *  obj.parent.child.prop = "some value";
		 *  // 然而使用lang.setObject：
		 *  lang.setObject("parent.child.prop", "some value", obj);
		 */
        setObject: function (name, value, context) {
            var parts = name.split("."), p = parts.pop(), obj = getProp(parts,
					true, context);
            return obj && p ? (obj[p] = value) : undefined; // Object
        },
        /**
		 * 获取用点分隔字符串的属性，如：A.B.C。
		 *
		 * @param {String}
		 *            name 属性的路径，如A.B.C
		 * @param {Boolean}
		 *            [create] 默认为false。如果为true，对易象不存在时将创建它。
		 * @param {Object}
		 *            [context = peach.global] 对象的作用域，默认为peach.global
		 * @return {Object | undefined} 返回对应的对象
		 */
        getObject: function (name, create, context) {
            return getProp(name.split("."), create, context);
        },
        /**
		 * 判断it是否为字符串
		 * @param {Anything} it 需要判断的值
		 * @return Boolean
		 */
        isString: function (it) {
            return (typeof it == "string" || it instanceof String);
        },
        /**
		 * 判断it是否为数字
		 * @param {Anything} it 需要判断的值
		 * @return Boolean
		 */
        isNumeric: function (it) {
            return !isNaN(parseFloat(obj)) && isFinite(obj);
        },
        /**
		 * 执行字符串参数的转换。如果任何参数都不匹配则抛出异常。
		 *
		 * @param {String} tmpl 作为模板的字符串
		 * @param {Object|Function} map 如果是对象，则使用字典来查找替换。如果是方法，则每次替换时调用，方法有以下参数：match、name、offset、template。
		 * @param {RegEx} [pattern] 正则表达式对象，覆盖默认的模式。
		 * @return {String} 返回替换后的字符串
		 * @example 使用字典替换
		 * lang.replace("Hello, {name.first} {name.last} AKA {nick}!" ,{
		 * 		nick: "Bob",
		 * 		name: {
		 * 			first:	"Robert",
		 * 			middle: "X",
		 * 			last:	"Cringely"
		 * 		}
		 * });
		 * // returns: Hello, Robert Cringely AKA Bob!
		 * @example 使用数组替换
		 *  lang.replace("Hello, {0} {2}!",["Robert", "X", "Cringely"]);
		 *  // returns: Hello, Robert Cringely!
		 * @example 使用类似PHP风格的方式替换
		 * lang.replace("Hello, ${0} ${2}!",["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
		 * // returns: Hello, Robert Cringely!
		 */
        replace: function (tmpl, map, pattern) {
            return tmpl.replace(pattern || _pattern, $.isFunction(map) ? map
					: function (_, k) {
					    return lang.getObject(k, false, map);
					});
        },
        /**
		 * 获取URL的参数的值
		 *
		 * @param {String} name URL的参数名称
		 * @return {String|null} 返回参数值，如果参数不存在，则返回null.
		 */
		getUrlQueryString:function (name) {
		    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
		    var r = window.location.search.substr(1).match(reg);
		    if (r != null) return unescape(r[2]); return null;
		},
        /**
		 * 延迟执行指定函数 fn
		 *
		 * @param {Function|String}
		 *            fn 延迟执行的函数
		 * @param {Number}
		 *            [when=0] 延迟时间, 单位是毫秒;
		 * @param {Boolean}
		 *            [periodic=false] 是不是周期性执行.
		 * @param {Object}
		 *            [context] 函数 fn 要执行时的上下文环境
		 * @param {Array}
		 *            [data] 传递的参数
		 * @return {Object} timer对象.
		 *         包含属性timer.id:定时器标识,timer.interval:是否周期执行;timer.cancel方法:取消定时器
		 */
        later: function (fn, when, periodic, context, data) {
            when = when || 0;
            var m = fn, d = $.makeArray(data), f, r;

            if (typeof fn === "string") {
                m = context[fn];
            }

            if (!m) {
                throw ('method undefined');
            }

            f = lang.hitch(context, m, d);

            r = (periodic) ? setInterval(f, when) : setTimeout(f, when);

            return {
                id: r,
                interval: periodic,
                cancel: function () {
                    if (this.interval) {
                        clearInterval(r);
                    } else {
                        clearTimeout(r);
                    }
                }
            };
        },
        /**
		 * 将 fn 缓存一段时间后, 再被调用执行
		 *
		 * @param {Function|String}
		 *            fn 要缓存的函数
		 * @param {Number}
		 *            [ms=150] 要缓存多长时间后执行, 默认是 150 ms;
		 * @param {Object}
		 *            [context] 函数 fn 要执行时的上下文环境
		 * @return {Function} 返回缓存后的函数对象;
		 */
        buffer: function (fn, ms, context) {
            ms = ms || 150;

            if (ms === -1) {
                return function () {
                    fn.apply(context || this, arguments);
                };
            }
            var bufferTimer = null;

            function f() {
                f.stop();
                bufferTimer = lang.later(fn, ms, false, context || this,
						arguments);
            }

            f.stop = function () {
                if (bufferTimer) {
                    bufferTimer.cancel();
                    bufferTimer = 0;
                }
            };

            return f;
        },
        /**
		 * 将需要长时间处理的数据，按时间分为几个区间进行执行，避免浏览器假死
		 *
		 * @param {Array}
		 *            data 要进行分批处理的数据
		 * @param {Function|String}
		 *            fn 要缓存的函数。该函数有两个参数：data的项与params
		 * @param {Object}
		 *            [context] 函数 fn 要执行时的上下文环境
		 * @param {Number}
		 *            [callback] data全部处理完成后调用该方法;
		 * @param {Object}
		 *            [params] 执行函数 fn 时传入的参数
		 * @return {Function} 返回缓存后的函数对象;
		 */
        batch: function (data, fn, context, callback, params) {
            if (!$.isArray(data))
                return;
            var timer = null;
            if (data.length > 0) {
                timer = setTimeout(function () {
                    var start = +new Date();
                    do {
                        var item = data.shift();
                        fn.call(context, item, params);
                    } while (data.length > 0 && (+new Date() - start < 50));
                    if (data.length > 0) {
                        timer = setTimeout(arguments.callee, 25);
                    } else {
                        callback && lang.later(callback, 0, false, context, [data]);
                    }
                }, 25);
            } else {
                callback && lang.later(callback, 0, false, context, [data]);
            }
            return {
                stop: function () {
                    if (timer) {
                        clearTimeout(timer);
                    }
                }
            };
        },
        /**
		 * 动态加载脚本文件
		 * @param { String } url 脚本的URL地址
		 * @param { Function | null } [success] 脚本加载成功后回调此函数
		 * @param { Boolean } [keepInhead=false] 脚本加载成功后是否将临时script元素保留在head中，默认不保留
		 */
        loadScript: function (url, success, keepInhead) {
            var head = document.getElementsByTagName('head')[0],
				script = document.createElement('script');
            script.src = url;
            script.onload = script.onreadystatechange = function () {
                if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') {
                    success && success();
                    script.onload = script.onreadystatechange = null;
                    if (!keepInhead) head.removeChild(script);
                }
            };
            head.appendChild(script);
            return this;
        },
        /**
		 * 停止事件冒泡与事件关联的默认动作
		 * @param { event } evt 需要停止冒泡及关联的默认动作的事件
		 */
        stopEvent: function (evt) {
            if (evt && evt.preventDefault) {
                evt.preventDefault();
                evt.stopPropagation();
            } else {
                evt = evt || window.event;
                evt.cancelBubble = true;
                evt.returnValue = false;
            }
        }
    };
    //lang.setObject("peach.base.lang", lang);
    lang.mixin(peach, lang);
    return lang;
});
/**
* @fileoverview
* 实现面向对象的设计，支持单继承、多继承、构造函数、调用父类方法、静态属性
*
* @author xudaosong
*/
/**
* peach库的基础组件
* @namespace peach.base
* @name peach.base
*
* @author xudaosong
*/
define('base/declare',["./kernel", "./lang"],function(peach, lang){
    var mix = lang._mixin, op = Object.prototype, opts = op.toString,
		xtor = new Function, counter = 0, cname = "constructor";

    function err(msg, cls) { throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }

    // C3算法排序(http://www.python.org/download/releases/2.3/mro/)
    function c3mro(bases, className) {
        var result = [], roots = [{ cls: 0, refs: []}], nameMap = {}, clsCount = 1,
			l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;

        // build a list of bases naming them if needed
        for (; i < l; ++i) {
            base = bases[i];
            if (!base) {
                err("mixin #" + i + " is unknown. Did you use peach.require to pull it in?", className);
            } else if (opts.call(base) != "[object Function]") {
                err("mixin #" + i + " is not a callable constructor.", className);
            }
            lin = base._meta ? base._meta.bases : [base];
            top = 0;
            // 添加基础信息到nameMap
            for (j = lin.length - 1; j >= 0; --j) {
                proto = lin[j].prototype;
                if (!proto.hasOwnProperty("declaredClass")) {
                    proto.declaredClass = "uniqName_" + (counter++);
                }
                name = proto.declaredClass;
                if (!nameMap.hasOwnProperty(name)) {
                    nameMap[name] = { count: 0, refs: [], cls: lin[j] };
                    ++clsCount;
                }
                rec = nameMap[name];
                if (top && top !== rec) {
                    rec.refs.push(top);
                    ++top.count;
                }
                top = rec;
            }
            ++top.count;
            roots[0].refs.push(top);
        }

        // 移除没有被引用的类
        while (roots.length) {
            top = roots.pop();
            result.push(top.cls);
            --clsCount;
            // 优化单联链
            while (refs = top.refs, refs.length == 1) {
                top = refs[0];
                if (!top || --top.count) {
                    // 分支或结束单链 => 不要结束根
                    top = 0;
                    break;
                }
                result.push(top.cls);
                --clsCount;
            }
            if (top) {
                // 分支
                for (i = 0, l = refs.length; i < l; ++i) {
                    top = refs[i];
                    if (! --top.count) {
                        roots.push(top);
                    }
                }
            }
        }
        if (clsCount) {
            err("can't build consistent linearization", className);
        }

        // 计算基类偏移
        base = bases[0];
        result[0] = base ?
			base._meta && base === result[result.length - base._meta.bases.length] ?
				base._meta.bases.length : 1 : 0;

        return result;
    }

    function inherited(args, a, f) {
        var name, chains, bases, caller, meta, base, proto, opf, pos,
			cache = this._inherited = this._inherited || {};

        // 分析参数
        if (typeof args == "string") {
            name = args;
            args = a;
            a = f;
        }
        f = 0;

        caller = args.callee;
        name = name || caller.nom;
        if (!name) {
            err("can't deduce a name to call inherited()", this.declaredClass);
        }

        meta = this.constructor._meta;
        bases = meta.bases;

        pos = cache.p;
        if (name != cname) {
            // 方法
            if (cache.c !== caller) {
                pos = 0;
                base = bases[0];
                meta = base._meta;
                if (meta.hidden[name] !== caller) {
                    // 发现错误
                    chains = meta.chains;
                    if (chains && typeof chains[name] == "string") {
                        err("calling chained method with inherited: " + name, this.declaredClass);
                    }
                    // 查找caller
                    do {
                        meta = base._meta;
                        proto = base.prototype;
                        if (meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)) {
                            break;
                        }
                    } while (base = bases[++pos]); // 重新分配
                    pos = base ? pos : -1;
                }
            }
            // 查找下一个
            base = bases[++pos];
            if (base) {
                proto = base.prototype;
                if (base._meta && proto.hasOwnProperty(name)) {
                    f = proto[name];
                } else {
                    opf = op[name];
                    do {
                        proto = base.prototype;
                        f = proto[name];
                        if (f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)) {
                            break;
                        }
                    } while (base = bases[++pos]); // 重新分配
                }
            }
            f = base && f || op[name];
        } else {
            // 构造
            if (cache.c !== caller) {
                pos = 0;
                meta = bases[0]._meta;
                if (meta && meta.ctor !== caller) {
                    // 发现错误
                    chains = meta.chains;
                    if (!chains || chains.constructor !== "manual") {
                        err("calling chained constructor with inherited", this.declaredClass);
                    }
                    // 查找caller
                    while (base = bases[++pos]) { // 重新分配
                        meta = base._meta;
                        if (meta && meta.ctor === caller) {
                            break;
                        }
                    }
                    pos = base ? pos : -1;
                }
            }
            // 查找下一个
            while (base = bases[++pos]) {	// 重新分配
                meta = base._meta;
                f = meta ? meta.ctor : base;
                if (f) {
                    break;
                }
            }
            f = base && f;
        }

        // 缓存基类
        cache.c = f;
        cache.p = pos;

        // 返回结果
        if (f) {
            return a === true ? f : f.apply(this, a || args);
        }
        // 如果没有发现基类
    }

    function getInherited(name, args) {
        if (typeof name == "string") {
            return this.inherited(name, args, true);
        }
        return this.inherited(name, true);
    }

    function isInstanceOf(cls) {
        var bases = this.constructor._meta.bases;
        for (var i = 0, l = bases.length; i < l; ++i) {
            if (bases[i] === cls) {
                return true;
            }
        }
        return this instanceof cls;
    }

    function mixOwn(target, source) {
        var name, i = 0, l = lang._extraNames.length;
        for (name in source) {
            if (name != cname && source.hasOwnProperty(name)) {
                target[name] = source[name];
            }
        }
        for (; i < l; ++i) {
            name = lang._extraNames[i];
            if (name != cname && source.hasOwnProperty(name)) {
                target[name] = source[name];
            }
        }
    }

    function safeMixin(target, source) {
        var name, t, i = 0, l = lang._extraNames.length;
        for (name in source) {
            t = source[name];
            if ((t !== op[name] || !(name in op)) && name != cname) {
                if (opts.call(t) == "[object Function]") {
                    t.nom = name;
                }
                target[name] = t;
            }
        }
        for (; i < l; ++i) {
            name = lang._extraNames[i];
            t = source[name];
            if ((t !== op[name] || !(name in op)) && name != cname) {
                if (opts.call(t) == "[object Function]") {
                    t.nom = name;
                }
                target[name] = t;
            }
        }
        return target;
    }

    function extend(source) {
        safeMixin(this.prototype, source);
        return this;
    }

    function chainedConstructor(bases, ctorSpecial) {
        return function () {
            var a = arguments, args = a, a0 = a[0], f, i, m,
				l = bases.length, preArgs;

            if (!(this instanceof a.callee)) {
                return applyNew(a);
            }

            if (ctorSpecial && (a0 && a0.preamble || this.preamble)) {
                preArgs = new Array(bases.length);
                preArgs[0] = a;
                for (i = 0; ; ) {
                    a0 = a[0];
                    if (a0) {
                        f = a0.preamble;
                        if (f) {
                            a = f.apply(this, a) || a;
                        }
                    }
                    f = bases[i].prototype;
                    f = f.hasOwnProperty("preamble") && f.preamble;
                    if (f) {
                        a = f.apply(this, a) || a;
                    }
                    if (++i == l) {
                        break;
                    }
                    preArgs[i] = a;
                }
            }
            for (i = l - 1; i >= 0; --i) {
                f = bases[i];
                m = f._meta;
                f = m ? m.ctor : f;
                if (f) {
                    f.apply(this, preArgs ? preArgs[i] : a);
                }
            }
            f = this.postscript;
            if (f) {
                f.apply(this, args);
            }
        };
    }

    function singleConstructor(ctor, ctorSpecial) {
        return function () {
            var a = arguments, t = a, a0 = a[0], f;

            if (!(this instanceof a.callee)) {
                // not called via new, so force it
                return applyNew(a);
            }
            if (ctorSpecial) {
                if (a0) {
                    f = a0.preamble;
                    if (f) {
                        t = f.apply(this, t) || t;
                    }
                }
                f = this.preamble;
                if (f) {
                    f.apply(this, t);
                }
            }
            if (ctor) {
                ctor.apply(this, a);
            }
            f = this.postscript;
            if (f) {
                f.apply(this, a);
            }
        };
    }

    function simpleConstructor(bases) {
        return function () {
            var a = arguments, i = 0, f, m;

            if (!(this instanceof a.callee)) {
                return applyNew(a);
            }

            for (; f = bases[i]; ++i) {
                m = f._meta;
                f = m ? m.ctor : f;
                if (f) {
                    f.apply(this, a);
                    break;
                }
            }
            f = this.postscript;
            if (f) {
                f.apply(this, a);
            }
        };
    }

    function chain(name, bases, reversed) {
        return function () {
            var b, m, f, i = 0, step = 1;
            if (reversed) {
                i = bases.length - 1;
                step = -1;
            }
            for (; b = bases[i]; i += step) {
                m = b._meta;
                f = (m ? m.hidden : b.prototype)[name];
                if (f) {
                    f.apply(this, arguments);
                }
            }
        };
    }


    function forceNew(ctor) {
        xtor.prototype = ctor.prototype;
        var t = new xtor;
        xtor.prototype = null;
        return t;
    }

    function applyNew(args) {
        var ctor = args.callee, t = forceNew(ctor);
        ctor.apply(t, args);
        return t;
    }
    /**
    * 创建一个类。
    *
    * @param {String|null} className 可选参数，声明的类的名称.这个类名会被用作创建的构造子的全局名称存储在"declaredClass"原型属性中，如果没有指定类名则使用全局名称。
    * @param {Function|Function[]|null} [superclass] 用于指定需要继承的基类。
    * @param {Object} props 一个对象，此对象所有的属性将混入到被创建的原型中。通过将一个属性命名为"constructor",你可以为创建的对象实例增加一个初始化函数。
    *
    * @memberOf peach.base
    * @return 返回新的类
    *
    * @example 创建类
    *	peach.declare("my.classes.bar", my.classes.foo, {
	*		// 定义类的属性添加到类的原型
	*		someValue: 2,
	*		// 初始化方法
	*		constructor: function(){
	*			this.myComplicatedObject = new ReallyComplicatedObject();
	*		},
	*		// 定义其它的类方法
	*		someMethod: function(){
	*			doStuff();
	*		}
	*	});
    *
	* @example 创建单继承及多继承的类
	*	var MyBase = peach.declare(null, {
	*		// TODO:构造方法、属性、其它的方法
	*		// ...
	*	});
	*	var MyClass1 = peach.declare(MyBase, {
	*		// TODO:构造方法、属性、其它的方法
	*		// ...
	*	});
	*	var MyClass2 = peach.declare(MyBase, {
	*		// TODO:构造方法、属性、其它的方法
	*		// ...
	*	});
	*	var MyDiamond = peach.declare([MyClass1, MyClass2], {
	*		// TODO:构造方法、属性、其它的方法
	*		// ...
	*	});

	* @example 实例化类及类的执行
	*	var F = function(){ console.log("raw constructor"); };
	*	F.prototype.method = function(){
	*		console.log("raw method");
	*	};
	*	var A = peach.declare(F, {
	*		constructor: function(){
	*			console.log("A.constructor");
	*		},
	*		method: function(){
	*			console.log("before calling F.method...");
	*			this.inherited(arguments);
	*			console.log("...back in A");
	*		}
	*	});
	*	new A().method();
	*	// 输出内容:
	*	// raw constructor
	*	// A.constructor
	*	// before calling F.method...
	*	// raw method
	*	// ...back in A

	* @example 构造函数及析构函数的执行
	*	var A = peach.declare(null, {
	*		"-chains-": {
	*			destroy: "before"
	*		}
	*	});
	*	var B = peach.declare(A, {
	*		constructor: function(){
	*			console.log("B.constructor");
	*		},
	*		destroy: function(){
	*			console.log("B.destroy");
	*		}
	*	});
	*	var C = peach.declare(B, {
	*		constructor: function(){
	*			console.log("C.constructor");
	*		},
	*		destroy: function(){
	*			console.log("C.destroy");
	*		}
	*	});
	*	new C().destroy();
	*	// 输出:
	*	// B.constructor
	*	// C.constructor
	*	// C.destroy
	*	// B.destroy

	* @example 调用基类的方法
	*	var A = peach.declare(null, {
	*		"-chains-": {
	*			constructor: "manual"
	*		}
	*	});
	*	var B = peach.declare(A, {
	*		constructor: function(){
	*			// ...
	*			// 使用新的参数调用基类的方法
	*			this.inherited(arguments, [1, 2, 3]);
	*			// ...
	*		}
	*	});

	* @example -chain-属性声明链式执行重写方法
	*	var A = peach.declare(null, {
	*		"-chains-": {
	*			m1: "before"
	*		},
	*		m1: function(){
	*			console.log("A.m1");
	*		},
	*		m2: function(){
	*			console.log("A.m2");
	*		}
	*	});
	*	var B = peach.declare(A, {
	*		"-chains-": {
	*			m2: "after"
	*		},
	*		m1: function(){
	*			console.log("B.m1");
	*		},
	*		m2: function(){
	*			console.log("B.m2");
	*		}
	*	});
	*	var x = new B();
	*	x.m1();
	*	// 输出:
	*	// B.m1
	*	// A.m1
	*	x.m2();
	*	// 输出:
	*	// A.m2
	*	// B.m2
    */
    function declare (className, superclass, props) {
        if (typeof className != "string") {
            props = superclass;
            superclass = className;
            className = "";
        }
        props = props || {};

        var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;

        if (opts.call(superclass) == "[object Array]") {
            bases = c3mro(superclass, className);
            t = bases[0];
            mixins = bases.length - t;
            superclass = bases[mixins];
        } else {
            bases = [0];
            if (superclass) {
                if (opts.call(superclass) == "[object Function]") {
                    t = superclass._meta;
                    bases = bases.concat(t ? t.bases : superclass);
                } else {
                    err("base class is not a callable constructor.", className);
                }
            } else if (superclass !== null) {
                err("unknown base class. Did you use peach.require to pull it in?", className);
            }
        }
        if (superclass) {
            for (i = mixins - 1; ; --i) {
                proto = forceNew(superclass);
                if (!i) {
                    break;
                }
                t = bases[i];
                (t._meta ? mixOwn : mix)(proto, t.prototype);
                ctor = new Function;
                ctor.superclass = superclass;
                ctor.prototype = proto;
                superclass = proto.constructor = ctor;
            }
        } else {
            proto = {};
        }
        // 添加所有的属性
        safeMixin(proto, props);
        // 添加构造函数
        t = props.constructor;
        if (t !== op.constructor) {
            t.nom = cname;
            proto.constructor = t;
        }

        for (i = mixins - 1; i; --i) {
            t = bases[i]._meta;
            if (t && t.chains) {
                chains = mix(chains || {}, t.chains);
            }
        }
        if (proto["-chains-"]) {
            chains = mix(chains || {}, proto["-chains-"]);
        }

        t = !chains || !chains.hasOwnProperty(cname);
        bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
			(bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));

        // 添加元数据
        ctor._meta = { bases: bases, hidden: props, chains: chains,
            parents: parents, ctor: props.constructor
        };
        ctor.superclass = superclass && superclass.prototype;
        ctor.extend = extend;
        ctor.prototype = proto;
        proto.constructor = ctor;

        // 添加公共方法
        proto.getInherited = getInherited;
        proto.inherited = inherited;
        proto.isInstanceOf = isInstanceOf;

        // 设置类名
        if (className) {
            proto.declaredClass = className;
            lang.setObject(className, ctor);
        }

        // 建立单链
        if (chains) {
            for (name in chains) {
                if (proto[name] && typeof chains[name] == "string" && name != cname) {
                    t = proto[name] = chain(name, bases, chains[name] === "after");
                    t.nom = name;
                }
            }
        }

        return ctor;
    };
    /**
    * 不包含构造函数的混入
    * @function
    * @param {Object} target 接受新属性的目标对象
    * @param {Object} source 源对象
    *
    * @return 返回target
    *
    */
    peach.safeMixin = declare.safeMixin = safeMixin;
    peach.declare = declare;
	return declare;
});
/**
 * @fileoverview 各个部件的基础组件，用于管理部件的生命周期及公共方法。
 * @author xudaosong
 */
 define('Widget',["./base/lang","./base/declare"],function(lang, declare){
	/**
	 * 各个部件的基础组件，用于管理部件的生命周期及公共方法。
	 * @namespace peach
	 * @name peach.Widget
	 */
	return declare("peach.Widget", null, /**@lends peach.Widget.prototype */{
		/**
		 * 部件的基础样式名称
		 * @type String
		 */
		baseClass : "",
		/**
		 * 部件的DOM容器
		 * @type DOMElement
		 */
		domNode : null,
		postscript : function(params, srcNodeRef) {
			if(!!srcNodeRef && typeof srcNodeRef === "string")
				this.domNode = $(srcNodeRef);
			else
				this.domNode = srcNodeRef;
			if(params){
				this.params = params;
				lang.mixin(this, params);
			}
			this.postCreate();
		},
		postCreate : function() {

		},
		destroy : function() {

		}
	});
});

/**
 * @fileoverview 该模块定义了DOM位置相关的API。
 * @author xudaosong
 */
/**
 * 该模块定义了DOM相关的API
 * @namespace peach
 * @name peach.dom
 */
 define('dom/domPosition',[
	"../jquery",
	"../base/lang"
 ], function($, lang){
	var $window=$(window);
	function doFixed(elem, settings){
        // 默认参数
        var options = {
            threshold : 0,                              // 触发元素显示的临界值
			endThreshold : null,
            position : { 'top' : 0, 'left' : 0 },       // 显示位置
            reset: null,
            timeout: 200
        },
        $elem = $(elem),
        //  元素的原始值
        original = {
            'display' : $elem.css('display'),
            'visibility' : $elem.css('visibility'),
            'position' : $elem.css('position')
        },
        positionNow = original.position,
        fixProperty = {
                'position' : 'fixed',
                'zIndex' : 9999
		 },
        ie6Handel = null,
        isIE6 = $.browser.msie && $.browser.version < 7;
        if($elem.is(":visible")){
        	$.extend(original, {
                top : $elem.css("top"),
                left: $elem.css("left"),
                right: $elem.css("right"),
                bottom: $elem.css("bottom")
        	});
        }

        $.extend(options, settings);
        if(options.reset === null ){
        	options.reset = original.position == 'absolute';
        }
		$.extend(fixProperty , options.position);
		var endThreshold = null;
        if(options.endThreshold !== null){
        	endThreshold =  options.endThreshold-$(window).height();
        	$(window).resize(function(){
        		endThreshold = options.endThreshold-$(this).height();
        	});
        }
        var _doFixed = function(){
        	 var top = $window.scrollTop();
        	 if(top >= options.threshold && (options.endThreshold === null ||  endThreshold >= top)){
        		 // 在阈值外，重新计算位置
        		 if(isIE6){
        			$elem.hide();
        			if(ie6Handel){
        				ie6Handel.cancel();
        			}
        			 ie6Handel = lang.later(function(){
        				 var o={
        					position : 'absolute'
        				 };
        				 if(options.position.top !== undefined)
        					 	o.top = top + options.position.top;
        				 $.extend(fixProperty, o);
        				 $elem.css(fixProperty).show();
             			 positionNow = "absolute";
             			 ie6Handel = null;
        			}, options.timeout);
        		 }else{
        			$elem.css(fixProperty).show();
        			positionNow = "fixed";
        		 }
        	 }else{
        		 // 在阈值内，还原位置
        			if( options.reset || isIE6){
    	           		$elem.css(original);
    	           		positionNow = original.position;
    	           	}
    	           	if ( ie6Handel ) {
    	           		ie6Handel.cancel();
                    }
        	 }
        };
        if(isIE6 || options.reset){
        	// 如果是IE6或者需要还原
            $window.bind("scroll resize" , _doFixed);
    	} else {
        	// 如果不是IE6并且不需要还原
    		$elem.css(fixProperty).show();
        }
    }
	var pos = /** @lends  peach.dom */{
		/**
		 * 在滚动时将指定的元素固定到指定的位置。支持特性如下：<br>
		 * 1. 支持元素在阀值外显示，在阀值内隐藏，如：返回顶部<br>
		 * 2. 支持元素在阀值外固定位置，在阀值内归位，如：淘宝的Tab菜单<br>
		 * 3. 支持元素在指阀值区间固定位置，不在区间内则归位。<br>
		 * 4. 支持所有浏览器，含ie6
		 * @param { DOMElment Array } elements 进行位置固定的元素集合
		 * @param { Object } [settings] 进行位置固定的相关配置
		 * @param { Integer } [settings.threshold = 0] 滚动到该阈值位开始固定
		 * @param { Integer } [settings.endThreshold = null] 滚动到该阈值位减去工作区的高度区间内进行固定，不在此区间则恢复
		 * @param { Object } [settings.position = { 'top' : 0, 'left' : 0 }] 元素固定的位置
		 * @param { Boolean } [settings.reset = null] 当元素在阈值内，是否恢复原始状态
		 * @param { Integer } [settings.timeout = 150] 如果是IE6浏览器，滚动时延迟多久处理一次，单位ms
		 * @returns { peach.dom }
		 */
		fixed: function(elements, settings){
			 $(elements).each(function(){
					new doFixed(this, settings);
			 });
			 return this;
		},
		/**
		 * 在滚动时将指定的元素固定到指定的位置，单击该元素时返回顶部。
		 * 支持特性如下：
		 * 1. 支持元素在阀值外显示，在阀值内隐藏，如：返回顶部
		 * 2. 支持元素在阀值外固定位置，在阀值内归位，如：淘宝的Tab菜单
		 * 3. 支持所有浏览器，含ie6
		 * @param { DOMElment Array } elements 进行位置固定的元素集合
		 * @param { Object } [settings] 进行位置固定的相关配置
		 * @param { Integer } [settings.threshold = 0] 滚动到该阈值位开始固定
		 * @param { Object } [settings.position = { 'top' : 0, 'left' : 0 }] 元素固定的位置
		 * @param { Boolean } [settings.reset = null] 当元素在阈值内，是否恢复原始状态
		 * @param { Integer } [settings.timeout = 150] 如果是IE6浏览器，滚动时延迟多久处理一次，单位ms
		 * @returns { peach.dom }
		 */
		goTop: function(elements, settings){
			$(elements).bind("click" , function(){
				$("html, body").animate({ scrollTop: 0 });
			});
			pos.fixed(elements, settings);
			return this;
		}
	};
	lang.mixin(lang.getObject("peach.dom", true), pos);
	return pos;
});
define('json',["./has"], function(has){

	var hasJSON = typeof JSON != "undefined";
	has.add("json-parse", hasJSON); // all the parsers work fine
		// Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
	has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');

	/*=====
	return {
		// summary:
		//		Functions to parse and serialize JSON

		parse: function(str, strict){
			// summary:
			//		Parses a [JSON](http://json.org) string to return a JavaScript object.
			// description:
			//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
			//		Throws for invalid JSON strings. This delegates to eval() if native JSON
			//		support is not available. By default this will evaluate any valid JS expression.
			//		With the strict parameter set to true, the parser will ensure that only
			//		valid JSON strings are parsed (otherwise throwing an error). Without the strict
			//		parameter, the content passed to this method must come
			//		from a trusted source.
			// str:
			//		a string literal of a JSON item, for instance:
			//		`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
			// strict:
			//		When set to true, this will ensure that only valid, secure JSON is ever parsed.
			//		Make sure this is set to true for untrusted content. Note that on browsers/engines
			//		without native JSON support, setting this to true will run slower.
		},
		stringify: function(value, replacer, spacer){
			// summary:
			//		Returns a [JSON](http://json.org) serialization of an object.
			// description:
			//		Returns a [JSON](http://json.org) serialization of an object.
			//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
			//		Note that this doesn't check for infinite recursion, so don't do that!
			// value:
			//		A value to be serialized.
			// replacer:
			//		A replacer function that is called for each value and can return a replacement
			// spacer:
			//		A spacer string to be used for pretty printing of JSON
			// example:
			//		simple serialization of a trivial object
			//	|	define(["dojo/json"], function(JSON){
			// 	|		var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
			//	|		doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
		}
	};
	=====*/

	if(has("json-stringify")){
		return JSON;
	}else{
		var escapeString = function(/*String*/str){
			// summary:
			//		Adds escape sequences for non-visual characters, double quote and
			//		backslash and surrounds with double quotes to form a valid string
			//		literal.
			return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
				replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
				replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
		};
		return window.JSON={
			parse: has("json-parse") ? JSON.parse : function(str, strict){
				if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
					throw new SyntaxError("Invalid characters in JSON");
				}
				return eval('(' + str + ')');
			},
			stringify: function(value, replacer, spacer){
				var undef;
				if(typeof replacer == "string"){
					spacer = replacer;
					replacer = null;
				}
				function stringify(it, indent, key){
					if(replacer){
						it = replacer(key, it);
					}
					var val, objtype = typeof it;
					if(objtype == "number"){
						return isFinite(it) ? it + "" : "null";
					}
					if(objtype == "boolean"){
						return it + "";
					}
					if(it === null){
						return "null";
					}
					if(typeof it == "string"){
						return escapeString(it);
					}
					if(objtype == "function" || objtype == "undefined"){
						return undef; // undefined
					}
					// short-circuit for objects that support "json" serialization
					// if they return "self" then just pass-through...
					if(typeof it.toJSON == "function"){
						return stringify(it.toJSON(key), indent, key);
					}
					if(it instanceof Date){
						return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
							var num = it["getUTC" + prop]() + (plus ? 1 : 0);
							return num < 10 ? "0" + num : num;
						});
					}
					if(it.valueOf() !== it){
						// primitive wrapper, try again unwrapped:
						return stringify(it.valueOf(), indent, key);
					}
					var nextIndent= spacer ? (indent + spacer) : "";
					/* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */

					var sep = spacer ? " " : "";
					var newLine = spacer ? "\n" : "";

					// array
					if(it instanceof Array){
						var itl = it.length, res = [];
						for(key = 0; key < itl; key++){
							var obj = it[key];
							val = stringify(obj, nextIndent, key);
							if(typeof val != "string"){
								val = "null";
							}
							res.push(newLine + nextIndent + val);
						}
						return "[" + res.join(",") + newLine + indent + "]";
					}
					// generic object code path
					var output = [];
					for(key in it){
						var keyStr;
						if(it.hasOwnProperty(key)){
							if(typeof key == "number"){
								keyStr = '"' + key + '"';
							}else if(typeof key == "string"){
								keyStr = escapeString(key);
							}else{
								// skip non-string or number keys
								continue;
							}
							val = stringify(it[key], nextIndent, key);
							if(typeof val != "string"){
								// skip non-serializable values
								continue;
							}
							// At this point, the most non-IE browsers don't get in this branch
							// (they have native JSON), so push is definitely the way to
							output.push(newLine + nextIndent + keyStr + ":" + sep + val);
						}
					}
					return "{" + output.join(",") + newLine + indent + "}"; // String
				}
				return stringify(value, "", "");
			}
		};
	}
});

/**
 * @fileoverview
 * Cookie模块
 *
 * @author xudaosong
 */
/**
* Cookie模块
* @namespace peach
* @name peach.cookie
*
* @author xudaosong
*/
define('cookie',["./base/kernel", "./base/lang"], function (peach, lang) {
    var doc = document,
        MILLISECONDS_OF_DAY = 24 * 60 * 60 * 1000,
        encode = encodeURIComponent,
        decode = decodeURIComponent;


    function isNotEmptyString(val) {
        return lang.isString(val) && val !== '';
    }

    window.cookie = /** @lends  peach.cookie */{
        /**
		 * 获取指定名称的cookie值。
		 * @param { String } name cookie的名称
         * @return {String} 返回name的cookie值
		 */
        get: function (name) {
            var ret, m;

            if (isNotEmptyString(name)) {
                if ((m = String(doc.cookie).match(
                    new RegExp('(?:^| )' + name + '(?:(?:=([^;]*))|;|$)')))) {
                    ret = m[1] ? decode(m[1]) : '';
                }
            }
            return ret;
        },
        /**
		 * 使用指定的名称和值设置cookie。
		 * @param { String } name cookie的名称
		 * @param { String } value cookie的值
         * @param {Number|Date} expires? cookie的过期时间，如果为数值则表示多少天数
         * @param {String} domain? cookie的domain
         * @param {String} path? cookie的path
         * @param {Boolean} secure? cookie是否只能在https协议下发送到服务器
		 */
        set: function (name, val, expires, domain, path, secure) {
            var text = String(encode(val)), date = expires;

            // 从当前时间开始，多少天后过期
            if (typeof date === 'number') {
                date = new Date();
                date.setTime(date.getTime() + expires * MILLISECONDS_OF_DAY);
            }
            // expiration date
            if (date instanceof Date) {
                text += '; expires=' + date.toUTCString();
            }

            // domain
            if (isNotEmptyString(domain)) {
                text += '; domain=' + domain;
            }

            // path
            if (isNotEmptyString(path)) {
                text += '; path=' + path;
            }

            // secure
            if (secure) {
                text += '; secure';
            }

            doc.cookie = name + '=' + text;
        },
        /**
         * 移除Cookie
         * @param {String} name cookie的名称.
         * @param {String} domain? cookie的domain
         * @param {String} path? cookie的path
         * @param {Boolean} secure? cookie的secure选项
         */
        remove: function (name, domain, path, secure) {
            this.set(name, '', -1, domain, path, secure);
        }
    };
    return cookie;
});
define('Validator',[
    "./jquery",
	"./base/lang",
	"./base/declare"
], function ($, lang, declare) {
    return declare("peach.Validator", null, {
        placeholder: "data-validator",
        context: window,
        container: null,
        errorClass: "validator_error",
        _counter: 0,
        constructor: function (params) {
            lang.mixin(this, params);
        },
        _validation: function (ele) {
            var msg = null, validate = ele.attr(this.placeholder);
            if (!!validate) {
                var value = ele.val(),
                    validate = $.parseJSON(validate);
                for (v in validate) {
                    if (v == "messages")
                        continue;
                    switch (v) {
						case "maxLength":
							if(ele.is("select")){
								if(ele[0].options.length>validate[v]){
									msg = validate["messages"][v];
								}
							} else if (!this[v](value, validate[v])) {
                                msg = validate["messages"][v];
                            }
							break;
                        case 'maxTo':
                        case "maxEqualTo":
						case "minEqualTo":
                            if (!this[v](ele, validate[v])) {
                                msg = validate["messages"][v];
                            }
                            break;
						case "custom":
							if (!this[v](value,ele,validate)) {
                                msg = validate["messages"][v];
                            }
							break;
                        default:
                            if (!this[v](value, validate[v])) {
                                msg = validate["messages"][v];
                            }
                            break;
                    }
                    if (!!msg) {
                        break;
                    }
                }
                return msg;
            }
        },
        /**
         * mini login valid
         */
        miniValid:function(){
            var context, isSuccess = true;
            context = $('.miniLogin').find("[" + this.placeholder + "]");
            context.each(lang.hitch(this, function (i, ele) {
                var msg = this._validation($(ele));
                if (!!msg) {
                    this.showMiniLoginError($(ele), msg);
                    isSuccess = false;
                    return false;
                }
            }));
            return isSuccess;
        },
        /**
         * for miniLogin Error
         * @By wangtuda
         */
        showMiniLoginError:function(ele,msg){
            var context = $('.miniLogin');
            ele.addClass(this.errorClass);
            context.find('#J_loginError').html(msg);
        },
        showLabel: function (ele, msg) {
            var label = $('<label/>').addClass(this.errorClass).html('<span>'+msg+'</span>');
            this.errorPlacement(label, ele);
            ele.addClass(this.errorClass);
            if (!!this.container) {
                this.container.append(label);
            }
        },
        errorPlacement: function (label, ele) {
            ele.parent().append(label);
        },
		clear: function(){
			$(this.context).find("label[class=" + this.errorClass + "]").remove();
            $(this.context).find("." + this.errorClass).removeClass(this.errorClass);
		},
        valid: function (dom) {
            this.clear();
            var context, isSuccess = true;
            if (!!dom) {
                context = $(dom);
            } else {
                context = $(this.context).find("[" + this.placeholder + "]");
            }
            context.each(lang.hitch(this, function (i, ele) {
                var msg = this._validation($(ele));
                if (!!msg) {
                    this.showLabel($(ele), msg);
                    isSuccess = false;
                }
            }));
            return isSuccess;
        },
        custom: function (value) {
            return true;
        },
        required: function (value) {
        	if(value==null)
        		return false;
        	else
        		return !(/^\s*$/).test(value);
        },
        range: function (value, params) {
            if (!this.required(value))
                return true;
            value = parseFloat(value);
            return params[0] <= value && value <= params[1];
        },
		rangeString: function(value,params){
            if (!this.required(value))
                return true;
			var length = value.length;
			return params[0] <= length && length <= params[1];
		},
        maxLength: function (value, maxLength) {
            if (!this.required(value))
                return true;
            return value.length <= maxLength;
        },
        date: function (value) {
            if (!this.required(value))
                return true;
            return !/Invalid|NaN/.test(new Date(value).toString());
        },
        number: function (value) {
            if (!this.required(value))
                return true;
            return /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
        },
        digits: function (value) {
            if (!this.required(value))
                return true;
            return /^\d+$/.test(value);
        },
		phoneNo: function(value){
            if (!this.required(value))
                return true;
			return /^[1]\d{10}$/.test(value);
		},
		image:function(value){
            if (!this.required(value))
                return true
            var data = value.split(".");
            if(data.length<=1)
            	return false;
            return /^(jpg|gif|png|bmp)$/i.test(data[data.length-1].toLocaleLowerCase());
		},
		url: function(value){
            if (!this.required(value))
                return true;
			return /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value)
		},
        maxTo: function (current, target) {
            current = $(current);
            if (!this.required(current.val()))
                return true;
            var cv = parseFloat(current.val());
            if (target === "prev") {
                tv = parseFloat(current.prev().val());
            } else {
                tv = parseFloat($(target).val());
            }
            return tv < cv;
        },
        maxEqualTo: function (current, target) {
            current = $(current);
            if (!this.required(current.val()))
                return true;
            var cv = parseFloat(current.val());
            if (target === "prev") {
                tv = parseFloat(current.prev().val());
            } else {
                tv = parseFloat($(target).val());
            }
            return tv <= cv;
        },
        minEqualTo: function (current, target) {
            current = $(current);
            if (!this.required(current.val()))
                return true;
            var cv = parseFloat(current.val());
            if (target === "prev") {
                tv = parseFloat(current.prev().val());
            } else {
                tv = parseFloat($(target).val());
            }
            return cv <= tv;
        },
		match:function(value,m){
			if (!this.required(value))
				return true;

			var k = new RegExp(m);
			return k.test(value);
		}
    });
});
/**
 * @fileoverview
 * 旋转木马组件
 * @author xudaosong
 * @version 1.0
 */
 define('Rotator',[
	"./jquery",
	"./base/lang",
	"./base/declare"
 ], function($, lang, declare){
	var _defaultTransition = "peach.rotator.swap",
	    _defaultTransitionDuration = 350;

	lang.setObject(_defaultTransition,
		/**
		 * 无动画直接切换的效果
		 * @name peach.rotator.swap
		 * @param { Object } [args] 切换面板的参数
		 */
		function(args){
			args.current.node.hide();
			args.next.node.show();
			args.onEnd && args.onEnd();
		});
      /**
  	 *	旋转木马。具备如下特性：
  	 * 1. 提供切换到任意面板的接口，切换方式支持标识与索引
  	 * 2. 支持上一页/下一页
  	 * 3. 支持附属面板元素，即不在容器下的元素
  	 * 4. 支持每个面板设置独立的动画切换效果
  	 * 5. 支持容器元素的动画前（onBeforeTransition）与动画后（onAfterTransition）的事件
  	 * 6. 支持动画切换插件
  	 * 依赖于peach.base.lang
  	 * @namespace peach
  	 * @name peach.Rotator_
  	 */
	return declare("peach.Rotator" , null ,  /** @lends peach.Rotator_.prototype */{
		/**
		 * 动画切换效果
		 * @default "peach.rotator.swap"
		 * @type String
		 */
		transition: _defaultTransition,
		/**
		 * 动画切换效果的参数
		 * @default duration: 350
		 * @type String
		 */
		transitionParams: "duration: " + _defaultTransitionDuration,
		/**
		 * 切换面板的集合
		 * @type Array
		 */
		panes: null,
		/**
		 * 当前显示面板的索引，从0开始
		 * @default 0
		 * @type Integer
		 */
		idx: 0,
		/**
		 * 旋转木马的构造函数。
		 * @param { Object | null } [params] 旋转木马的参数初始化对象
		 * @param { DOMElement l String } [node] 旋转木马的容器元素
		 */
		constructor: function(params, node){
			// 参数初始化
			lang.mixin(this, params);

			var idMap = this._idMap = {},
				 domNode = this.domNode = $(node),
				 idx = this.idx,
				 transition = this.transition,
				 transitions = this._transitions = {},
				 transitionParams = this.transitionParams = eval("({ " + this.transitionParams + " })"),
				 domNodeBox = this._rotatorBox = {w: domNode.width(), h: domNode.height()},
				 p={
				 	position : "absolute",
				 	left: 0,
				 	top: 0,
				 	zIndex: 0
				 };
			 // 确保容器的子元素能进行绝对定位
			 if(domNode.css("position") == "static"){
				 domNode.css("position" , "relative");
			 }
			 // 缓存切换动画效果
			 transitions[transition] = lang.getObject(transition) ;
			 // 如果切换动画效果不存在，则使用默认的切换动画效果
			 if(!transitions[transition]){
				 transitions[this.transition = _defaultTransition] = lang.getObject(_defaultTransition);
			 }
			 // 如果没有设置动画时间，则使用默认动画时间
			 if(!transitionParams.duration){
				 transitionParams.duration = _defaultTransitionDuration;
			 }
			 // 如果panes有值，则追加到容器中
			 if(this.panes){
				 $.each(this.panes, function(p){
					 	domNode.append($("<div/>").append(p));
				});
			 }
			 var panes = this.panes = [];
			 // 所有容器的子元素初始化。
			 // 1. 隐藏所有的子元素并设置元素的默认样式
			 // 2. 将所有子元素缓存到panes并且增加扩展属性
			domNode.children().hide().css(p).each(function(i,n){
				var $n = $(n),
					  q = {
					  		node: $n,
							idx: i,
							params: lang.mixin({}, transitionParams, eval("({ " + ($n.data("transitionParams") || "") + " })")),
							trans: $n.data("transition") || transition
					  };
				$.each(["id","title"],function(i, n){
					q[n] = $n.attr(n);
				});
				if(q.id){
					// 确保能使用ID定位
					idMap[q.id] = i;
				}
				// 检查并缓存切换动画效果
				if(!transitions[q.trans] && !(transitions[q.trans] = lang.getObject(q.trans))){
					console.warn("function not defined: ", q.trans);
				}
				panes.push(q);
			});
			// 显示1张图
			panes[idx].node.show();
		},
		/**
		 * 切换到下一个面板，如果当前是最后一个，则下一个是第1个
		 */
		next: function(){
			return this.go(this.idx + 1);
		},
		/**
		 * 切换到上一个面板，如果当前是第一个，则上一个是最后一个
		 */
		prev: function(){
			return this.go(this.idx - 1);
		},
		/**
		 * 切换到指定索引或标识的面板
		 * @param { Integer | String } [p] 切换面板的索引或标识，索引从0开始
		 */
		go: function(p){
			var self = this,
				  i = self.idx,
				  panes = self.panes,
				  len = panes.length,
				  idm = self._idMap[p];
			p = idm != null ? idm : (p || 0);
			p = p < len ? (p < 0 ? len-1 : p) : 0;

			if(p == i || self.anim){
				return null;
			}
			var current = panes[i],
				next = panes[p],
				info = {
					current: current,
					next: next,
					rotator: self
				};
			var end = function(){
					current.node.css({
						display: "none",
						left: 0,
						opacity: 1,
						top: 0,
						zIndex: 0
					});
					next.node.css({zIndex: 1});
					self.anim = null;
					self.idx = p;
					self.domNode.trigger("onAfterTransition", [i, p, self]);
					self.anim = false;
				};
			self.domNode.trigger("onBeforeTransition", [i, p, self]);
			self.anim = true;
			// 调用动画库转入的参数有：rotatorBox（窗口的宽高）、onEnd（动画完成后的回调函数）、current（当前元素）、next（下一个元素）、rotator（当前的旋转木马对象）、params（动画的相关参数）
			self._transitions[next.trans](lang.mixin({
				rotatorBox: self._rotatorBox,
				onEnd: end
			}, info, next.params));
		},
		/**
		 * 用于当前实例的方法调用
		 * @param { Array } [action] 数组的第1个值为方法名，其它的值为该方法传入的参数
		 */
		control: function(action){
			var args = lang._toArray(arguments),
				_t = this;
			args.shift();
			if(_t[action]){
				_t[action].apply(_t, args);
			}
		}
	});
 });
/**
 * @fileoverview
 * 自动的旋转木马
 * @author xudaosong
 */
 define('AutoRotator',[
	"./Rotator",
	"./base/lang",
	"./base/declare"
 ], function(Rotator, lang, declare){
	/**
	 * 自动的旋转木马。具备如下特性：
	 * 1. 自动开始
	 * 2. 鼠标停留时暂停
	 * 3. 支持播放和暂停
	 * 该模块继承自peach.Rotator，依赖于peach.base.lang
	 * @see peach.Rotator_
	 * @extends peach.Rotator_
	 * @namespace peach
	 * @name peach.AutoRotator
	 */
	return declare("peach.AutoRotator", Rotator, /** @lends peach.AutoRotator.prototype */{
		/**
		 * 鼠标停留在元素上时暂停播放
		 * @default false
		 * @type Boolean
		 */
		suspendOnHover: false,
		/**
		 * 自动播放的时间间隔
		 * @default 3000
		 * @type Integer
		 */
		duration: 3000,
		/**
		 * 初始化后是否自动开始播放
		 * @default true
		 * @type Boolean
		 */
		autoStart: true,
		/**
		 * 计时器对象
		 */
		_timer: null,
		constructor: function(){
			if(this.suspendOnHover){
				this.domNode.bind("mouseenter", lang.hitch(this, this.pause)).bind("mouseleave", lang.hitch(this, this.play));
			}
			if(this.autoStart && this.panes.length > 1){
				this.play();
			}else{
				this.pause();
			}
		},
		/**
		 * 开始自动播放。
		 * @param { event | null } [e] 如果是事件则停止冒泡。
		 */
		play: function(e){
			if(typeof e == "object"){
				lang.stopEvent(e);
			}
			if(!this._timer){
				this._timer = lang.later(this.next, this.duration, true, this);
				this.domNode.trigger("onPlay");
			}
		},
		/**
		 * 暂停播放
		 * @param { event | null } [e] 如果是事件则停止冒泡。
		 */
		pause: function(e){
			if(typeof e == "object"){
				lang.stopEvent(e);
			}
			if(this._timer){
				this._timer.cancel();
				this._timer = null;
				this.domNode.trigger("onPause");
			}
		}
	});
 });
/**
 * @fileoverview
 * 旋转木马的控制杠
 * @author xudaosong
 */
 define('rotator/Controller',[
	"../base/lang",
	"../base/declare"
 ], function(lang, declare){
	var _rotator = "rotator",
		  _play = _rotator + "Play",
		  _pause = _rotator + "Pause",
		  _next = _rotator + "Next",
		  _prev = _rotator + "Prev",
		  _number = _rotator + "Number",
		  _selected = _rotator + "Selected";
	/**
	 * 旋转木马的控制杠，依赖于peach.base.lang和peach.Rotator。具备如下特性：
	 * 1. 支持自动生成列表控制器
	 * 2. 支持上一页/下一页与播放/暂停控制器
	 * 3. 支持自定义控制器
	 * 4. 支持不同的切换事件
	 * 4. 与AutoRotator整合，使suspendOnHover在控制器上同样有效
	 * @see peach.Rotator
	 * @namespace peach.rotator
	 * @name peach.rotator.Controller
	 */
	return declare("peach.rotator.Controller", null, /** @lends peach.rotator.Controller */{
		/**
		 * 与该控制器关联的旋转木马的对象
		 * @type peach.Rotator
		 */
		rotator: null,
		/**
		 * 生成控制器的命令，控制器生成的先后顺序为命令定义的先后顺利。除custom命令必须单独使用外，其它的命令能混合使用，多命令之间用逗号分隔，如：prev,#,next，
		 * 目前有如下命令：
		 * #：默认值，用于生成列表控制器，如：1、2、3、4
		 * prev: 上一页控制器
		 * next: 下一页控制器
		 * play/pause: 播放/暂停控制器
		 * custom: 自定义控制器
		 * @default "#"
		 * @type String
		 */
		commands: "#",
		/**
		 * 触发动画切换的事件，默认为click，如果是多个事件用空格分隔，如："mouseenter mousemove"
		 * @default "click"
		 * @type String
		 */
		event: "click",
		/**
		 * 旋转木马控制杠的构造函数。
		 * @param { Object } [params] 控制杠的参数初始化对象，rotator对象是必须设置的
		 * @param { DOMElement l String } [node] 控制杠的容器元素，如果commands是custom则必须是控制杠元素的集合（即实际触发切换动画的元素）
		 */
		constructor: function(params, node){
			lang.mixin(this, params);
			var n = this.domNode = $(node),
				  r = this.rotator,
				  event = this.event;
			if(r){
				if(this.commands == "custom"){
					n.addClass(_number);
					this._update(n);
				} else {
					var ul =  $("<ul/>");
					var	cb = function(label, css, action){
						var li = $("<li/>").data("goto", action).addClass(css).append('<a href="javascript:;"><span>' + label + '</span></a>');
						ul.append(li);
					};
					$.each(this.commands.split(','), function(i,n){
						switch(n){
							case "#":
								for(var j=0; j<r.panes.length; j++){
									cb(j+1, _number, ["go" , j]);
								}
								break;
							case "prev":
								cb("prev",  _prev, ["prev"])
								break;
							case "next":
								cb("next",  _next, ["next"])
								break;
							case "play/pause":
								cb("Play", _play, ["play"]);
								cb("Pause", _pause, ["pause"]);
								break;
						}
					});
					this._update(ul.children());
					n.append(ul);
				}
			}
		},
		/**
		 * 用于更新各类效果，如：选中项、播放\暂停、效果初始化
		 */
		_update: function(n){
			var self = this,
				  r = self.rotator;
			// 订阅需要进行动画切换的事件
			n.bind(self.event, lang.buffer(function(e){
				lang.stopEvent(e);
				if(r){
					// 触发方法回调，进行动画切换
					r.control.apply(r, eval($(this).data("goto")));
				}
			}, 50));
			// 如果开启了鼠标停留在容器上暂停播放，则订阅mouseenter与mouseleave事件回调pause/play方法。
			if(r.suspendOnHover){
				n.bind("mouseenter", lang.buffer(r.pause, 50, r)).bind("mouseleave", lang.buffer(r.play, 50, r));
			}
			r.domNode.bind("onBeforeTransition", function(event, current, next, obj){
				// 在切换动画前触发此方法，用于设置项的选中效果
				lang.stopEvent(event);
				n.filter("." + _selected).removeClass(_selected);
				n.filter("." + _number + ":eq(" + next + ")").addClass(_selected);
			}).bind("onPlay", function(){
				// 在开始播放的时候触发此方法，用于切换播放/暂停的按钮
				n.filter("."+_play).hide();
				n.filter("."+_pause).show();
			}).bind("onPause", function(){
				// 在暂停播放的时候触发此方法，用于切换播放/暂停的按钮
				n.filter("."+_pause).hide();
				n.filter("."+_play).show();
			});
			// 选中项的初始化
			n.filter("." + _number + ":eq(" + r.idx + ")").addClass(_selected);
			// 播放/暂停的初始化
			r.domNode.trigger(r.autoStart ? "onPlay" : "onPause");
		}
	});
});
/**
 * @fileoverview
 * 旋转木马的上下左右幻灯片的切换效果
 * @author xudaosong
 */
define('rotator/slide',[
	"../base/lang"
],function(lang){
	var DOWN = 0,
		RIGHT = 1,
		UP = 2,
		LEFT = 3;
	function _slide(type, args){
		var node = args.next.node,
			  r = args.rotatorBox,
			  m = type % 2,
			  a = m ? "left" : "top",
			  s = (m ? r.w : r.h) * (type < 2 ? -1 : 1);

		node.css("zIndex", 2).show();
		if(!args.properties){
			args.properties = {};
		}
		args.properties[a] = 0;
		node.css(a, s);
		return node.animate(
						args.properties,
						args.duration,
						args.easing,
						args.onEnd);
	}
	var exports =  /** @lends peach.rotator */{
			/**
			 * 向下幻灯片的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			slideDown: function(args){
				return _slide(DOWN, args);
			},
			/**
			 * 向右幻灯片的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			slideRight: function(args){
				return _slide(RIGHT, args);
			},
			/**
			 * 向上幻灯片的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			slideUp: function(args){
				return _slide(UP, args);
			},
			/**
			 * 向左幻灯片的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			slideLeft: function(args){
				return _slide(LEFT, args);
			}
	};
	lang.mixin(lang.getObject("peach.rotator", true), exports);
	return exports;
});
/**
 * @fileoverview
 * 旋转木马的淡入/淡出切换效果
 * @author xudaosong
 */
/**
 * 旋转木马的相关配套组件，如控制器、各种切换效果
 * @namespace peach
 * @name peach.rotator
 */
define('rotator/fade',[
	"../base/lang"
],function(lang){
	function _fade(args, action){
		var n = args.next.node;
		if(action == "combine"){
			args.current.node.fadeOut(args.duration, args.easing);
			return n.fadeIn(args.duration, args.easing, args.onEnd);
		} else {
			args.current.node.fadeOut(args.duration, args.easing, function(){
				return n.fadeIn(args.duration, args.easing, args.onEnd);
			});
		}
	}

	var exports = /** @lends peach.rotator */{
			/**
			 * 淡入/淡出串行切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			fade: function(args){
				return _fade(args, "chain");
			},
			/**
			 * 淡入/淡出并行切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			crossFade: function(args){
				return _fade(args, "combine");
			}
	};
	lang.mixin(lang.getObject("peach.rotator", true), exports);
	return exports;
});
/**
 * @fileoverview
 * 旋转木马的上下左右滚动的切换效果
 * @author xudaosong
 */
define('rotator/scroll',[
	"../base/lang"
],function(lang){
	var DOWN = 0,
		  RIGHT = 1,
		  UP = 2,
		  LEFT = 3;
	function _scroll(type, args){
		var n = args.next.node,
			  r = args.rotatorBox,
			  m = type % 2,
			  a = m ? "left" : "top",
			  s = (m ? r.w : r.h) * (type < 2 ? -1 : 1),
			  p = {},
			  q = {};
		n.css(a, s).show();
		q[a] = 0;
		p[a] = -s;
		args.current.node.animate(p, args.duration, args.easing)
		return n.animate(q, args.duration, args.easing, args.onEnd)
	}
	var exports = /** @lends peach.rotator */ {
			/**
			 * 向下滚动的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			scrollDown: function(args){
				return _scroll(DOWN, args);
			},
			/**
			 * 向右滚动的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			scrollRight: function(args){
				return _scroll(RIGHT, args);
			},
			/**
			 * 向上滚动的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			scrollUp: function(args){
				return _scroll(UP, args);
			},
			/**
			 * 向左滚动的切换效果
			 * @param { Object } [args] 动画效果的参数，如duration,easing,onEnd
			 */
			scrollLeft: function(args){
				return _scroll(LEFT, args);
			}
	};
	lang.mixin(lang.getObject("peach.rotator", true), exports);
	return exports;
});
/**
 * @fileoverview
 * 用于加载基础组件
 *
 * @author xudaosong
 */
define('peach',[
    "./require",
    "./jquery",
    "./base/kernel",
    "./base/lang",
    "./base/declare",
    "./Widget",
    "./has",
    "./dom/domPosition",
    "./json",
    "./cookie",
    "./Validator",
    "./Rotator",
    "./AutoRotator",
    "./rotator/Controller",
    "./rotator/slide",
    "./rotator/scroll"
], function(req, jq, peach){
    return peach;
});